﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using LGE;

namespace TileMapEditor
{
    class EditScreen : GameScreen
    {
        String blockFilePath = "0.block";
        int scrollVelocity = 10;
        int blockAreaX = 120;

        Block block;

        // variables
        int layerSelected = 1;
        int codeL = 1;
        int codeR = 0;
        int listPos = 0;
        int maxListItens = 10;

        // UI
        Texture2D leftpanel;
        CheckBox upArrow;
        CheckBox downArrow;
        Button loadButton;
        Button saveButton;
        Dictionary<int, Button> menu0;
        Dictionary<int, Button> menu1;
        CheckBox drawLayer0cb;
        CheckBox drawLayer1cb;
        CheckBox drawLayer2cb;
        CheckBox selectLayer0cb;
        CheckBox selectLayer1cb;
        CheckBox selectLayer2cb;

        public EditScreen()
            : base()
        {
        }

        public override void LoadContent()
        {
            leftpanel = Engine.Load<Texture2D>("leftpanel");
            menu0 = new Dictionary<int, Button>();
            menu1 = new Dictionary<int, Button>();

            int i = 0;
            bool t = false;
            foreach (KeyValuePair<int, Texture2D> pair in Tile.Textures)
                if ((t = !t))
                    menu0.Add(pair.Key, new Button(pair.Value, new Vector2(43 - Tile.Size / 2, 290 - Tile.Size / 2 + (Tile.Size + 10) * i), 1));
                else
                    menu1.Add(pair.Key, new Button(pair.Value, new Vector2(77 - Tile.Size / 2, 290 - Tile.Size / 2 + (Tile.Size + 10) * i++), 1));

            block = new Block();
            block.position = new Vector2(blockAreaX + Tile.Size, Tile.Size);//8, 7
            upArrow = new CheckBox(Engine.Load<Texture2D>("Buttons\\upArrow"), new Vector2(52, 252));
            downArrow = new CheckBox(Engine.Load<Texture2D>("Buttons\\downArrow"), new Vector2(52, 672));
            loadButton = new Button(Engine.Load<Texture2D>("Buttons\\load"), new Vector2(10, 18));
            saveButton = new Button(Engine.Load<Texture2D>("Buttons\\save"), new Vector2(10, 80));
            drawLayer0cb = new CheckBox(Engine.Load<Texture2D>("Buttons\\botao_view"), new Vector2(41, 162));
            drawLayer1cb = new CheckBox(Engine.Load<Texture2D>("Buttons\\botao_view"), new Vector2(67, 162));
            drawLayer2cb = new CheckBox(Engine.Load<Texture2D>("Buttons\\botao_view"), new Vector2(94, 162));
            selectLayer0cb = new CheckBox(Engine.Load<Texture2D>("Buttons\\layer_selecionado"), new Vector2(39, 139));
            selectLayer1cb = new CheckBox(Engine.Load<Texture2D>("Buttons\\layer_selecionado"), new Vector2(65, 139));
            selectLayer2cb = new CheckBox(Engine.Load<Texture2D>("Buttons\\layer_selecionado"), new Vector2(92, 139));
            selectLayer0cb.Checked = false;
            selectLayer2cb.Checked = false;
        }

        public override void Update(GameTime gameTime)
        {
            if (!Engine.game.IsActive) return;
            UpdateMouse();
            UpdateKeyboard();
            selectLayer0cb.Checked = layerSelected == 0;
            selectLayer1cb.Checked = layerSelected == 1;
            selectLayer2cb.Checked = layerSelected == 2;
        }

        public void UpdateKeyboard()
        {
            if (Input.KeyDown(Keys.Left)) MoveBlock(Direction.Left);
            if (Input.KeyDown(Keys.Right)) MoveBlock(Direction.Right);
            if (Input.KeyDown(Keys.Up)) MoveBlock(Direction.Up);
            if (Input.KeyDown(Keys.Down)) MoveBlock(Direction.Down);
            if (Input.KeyPressed(Keys.D1)) layerSelected = 0;
            if (Input.KeyPressed(Keys.D2)) layerSelected = 1;
            if (Input.KeyPressed(Keys.D3)) layerSelected = 2;
            if (Input.KeyPressed(Keys.Q)) drawLayer0cb.Checked = !drawLayer0cb.Checked;
            if (Input.KeyPressed(Keys.W)) drawLayer1cb.Checked = !drawLayer1cb.Checked;
            if (Input.KeyPressed(Keys.E)) drawLayer2cb.Checked = !drawLayer2cb.Checked;
            if (Input.KeyPressed(Keys.S)) GameScreenManager.ChangeScreen(new ChangeSizeScreen());
            if (Input.KeyPressed(Keys.PageUp)) MoveList(-1);
            if (Input.KeyPressed(Keys.PageDown)) MoveList(1);
        }

        public void UpdateMouse()
        {
            // lista de tiles
            for (int i = listPos; i < listPos + maxListItens; ++i)
                if (i >= (menu0.Values.ToArray<Button>().Count<Button>())) continue;
                else if (menu0.Values.ToArray<Button>()[i].Clicked) { codeL = menu0.Keys.ToArray<int>()[i]; return; }
                else if (menu0.Values.ToArray<Button>()[i].RClicked) { codeR = menu0.Keys.ToArray<int>()[i]; return; }
                else if (i >= (menu1.Values.ToArray<Button>().Count<Button>())) continue;
                else if (menu1.Values.ToArray<Button>()[i].Clicked) { codeL = menu1.Keys.ToArray<int>()[i]; return; }
                else if (menu1.Values.ToArray<Button>()[i].RClicked) { codeR = menu1.Keys.ToArray<int>()[i]; return; }

            // load
            if (loadButton.Clicked) { block = Block.Load(blockFilePath); block.position = new Vector2(blockAreaX + Tile.Size, Tile.Size); return; }
            // save
            if (saveButton.Clicked) { block.Save(blockFilePath); return; }

            // draw layer buttons
            if (drawLayer0cb.Clicked) drawLayer0cb.Checked = !drawLayer0cb.Checked;
            if (drawLayer1cb.Clicked) drawLayer1cb.Checked = !drawLayer1cb.Checked;
            if (drawLayer2cb.Clicked) drawLayer2cb.Checked = !drawLayer2cb.Checked;

            // select layer buttons
            if (selectLayer0cb.Clicked) layerSelected = 0;
            if (selectLayer1cb.Clicked) layerSelected = 1;
            if (selectLayer2cb.Clicked) layerSelected = 2;

            // arrow
            if (downArrow.Clicked) MoveList(1);
            if (upArrow.Clicked) MoveList(-1);

            // block
            if (Input.MouseDown && Input.MousePos.X >= blockAreaX && Input.MousePos.Y >= 0 && Input.MousePos.X < Engine.viewport.Width && Input.MousePos.Y < Engine.viewport.Height)
            {
                Point p = block.GetCoord(Input.MousePos);
                if (!(p.X < 0 || p.Y < 0 || p.X > Block.Width - 1 || p.Y > Block.Height - 1))
                    block.map[layerSelected][p.Y][p.X] = codeL;
                return;
            }
            if (Input.MouseRDown && Input.MousePos.X >= blockAreaX && Input.MousePos.Y >= 0 && Input.MousePos.X < Engine.viewport.Width && Input.MousePos.Y < Engine.viewport.Height)
            {
                Point p = block.GetCoord(Input.MousePos);
                if (!(p.X < 0 || p.Y < 0 || p.X > Block.Width - 1 || p.Y > Block.Height - 1))
                    block.map[layerSelected][p.Y][p.X] = codeR;
                return;
            }
        }

        public void MoveList(int x)
        {
            listPos += x;
            if (listPos > Math.Max(menu0.Count, menu1.Count) - maxListItens)
            {
                listPos = Math.Max(menu0.Count, menu1.Count) - maxListItens;
                if (listPos < 0) listPos = 0;
            }
            else if (listPos < 0) listPos = 0;
            else
            {
                foreach (Button b in menu0.Values) b.position.Y -= x * (Tile.Size + 10);
                foreach (Button b in menu1.Values) b.position.Y -= x * (Tile.Size + 10);
            }
        }

        public void MoveBlock(Vector2 dir)
        {
            Vector2 p = block.position - dir * scrollVelocity;
            if (!(p.Y < -(Block.Height - 1) * Tile.Size
               || p.Y > Engine.viewport.Height - Tile.Size
               || p.X > Engine.viewport.Width - Tile.Size
               || p.X < -(Block.Width - 1) * Tile.Size + blockAreaX
               ))
                block.position = p;
        }

        public override void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {
            // desenha o grid por trás
            DrawGrid(spriteBatch);

            // desenha o bloco
            if (drawLayer0cb.Checked) block.Draw(spriteBatch, 0);
            if (drawLayer1cb.Checked) block.Draw(spriteBatch, 1);
            if (drawLayer2cb.Checked) block.Draw(spriteBatch, 2);

            // desenha o leftpanel
            spriteBatch.Draw(leftpanel, Vector2.Zero, Color.White);

            // desenha os botões
            loadButton.Draw(spriteBatch);
            saveButton.Draw(spriteBatch);
            drawLayer0cb.Draw(spriteBatch);
            drawLayer1cb.Draw(spriteBatch);
            drawLayer2cb.Draw(spriteBatch);
            selectLayer0cb.Draw(spriteBatch);
            selectLayer1cb.Draw(spriteBatch);
            selectLayer2cb.Draw(spriteBatch);
            downArrow.Draw(spriteBatch);
            upArrow.Draw(spriteBatch);

            // desenha os tiles que estão no mouse
            Vector2 origin = new Vector2(Tile.Textures[codeL].Width / 2, Tile.Textures[codeL].Height / 2);
            spriteBatch.Draw(Tile.Textures[codeL], new Vector2(41, 213) - origin, Color.White); //(20, 170)
            spriteBatch.Draw(Tile.Textures[codeR], new Vector2(77, 213) - origin, Color.White); //(70, 170)

            // desenha a lista de tiles
            for (int i = listPos; i < listPos + maxListItens; ++i)
            {
                if (i < menu0.Values.ToArray<Button>().Count<Button>())
                    menu0.Values.ToArray<Button>()[i].Draw(spriteBatch);
                if (i < menu1.Values.ToArray<Button>().Count<Button>())
                    menu1.Values.ToArray<Button>()[i].Draw(spriteBatch);
            }
        }

        public void DrawGrid(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < Block.Height; i++)
                for (int j = 0; j < Block.Width; j++)
                    spriteBatch.Draw(Tile.Textures[0], block.position + new Vector2(j * Tile.Size, i * Tile.Size), Color.White);
        }
    }
}
